/**
 * TDS PEC 4
 * Grupo 3H2M 
 *
 * El paquete <code>edu.uoc.tds.pec4.server.impl</code> agrupa todas las clases
 * que encapsulan la implementación de los métodos de acceso RMI y el servidor.
 */
package edu.uoc.tds.pec4.server.impl;

import edu.uoc.tds.pec4.beans.CFisicaDTO;
import edu.uoc.tds.pec4.beans.EquipamientoDTO;
import edu.uoc.tds.pec4.beans.LocalizacionDTO;
import edu.uoc.tds.pec4.beans.RolDTO;
import edu.uoc.tds.pec4.beans.SolicitudDTO;
import edu.uoc.tds.pec4.beans.UsuarioDTO;
import edu.uoc.tds.pec4.common.util.Constantes;
import edu.uoc.tds.pec4.rmi.GestorConexionInterface;
import edu.uoc.tds.pec4.server.bbdd.DAOFactory;
import edu.uoc.tds.pec4.server.bbdd.ISolicitudDAO;
import edu.uoc.tds.pec4.server.bbdd.IUsuarioDAO;
import edu.uoc.tds.pec4.server.bbdd.exceptions.DAOFactoryException;
import edu.uoc.tds.pec4.server.bbdd.exceptions.DataBaseDAOException;
import edu.uoc.tds.pec4.server.bbdd.exceptions.GestorConexionException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

/**
 * La clase <code>GestorConexionImpl</code> contiene la implementación de
 * todos los  métodos indicados en la interfaz <code>GestorIndicenciasInterface</code><br />
 * Clase que implementa todas las funciones remotas que se pueden solicitar por RMI. <br />
 *
 * Representa el objeto remoto que se invoca en la comunicación RMI.
 *
 * @author	Jaime Marcos
 * @version	08/12/2011
 */
public class GestorConexionImpl extends UnicastRemoteObject implements GestorConexionInterface {

    /**
     * Constructor
     * @throws	RemoteException en caso de producirse un fallo de comunicaciones
     */
    public GestorConexionImpl() throws RemoteException {
        super();
    }

    /**
     * Devuelve el usuario que corresponde con el login.
     * @param   login    el login para buscar si es correcto
     * @return  el usuario que le corresponde el login pasado por parametro
     * @throws  RemoteException en caso de producirse un fallo de comunicaciones
     * @throws  GestorConexionException En caso de producirse un error en el acceso
     *          a datos
     */
    @Override
    public UsuarioDTO consultarUsuario(String login) throws RemoteException, GestorConexionException {
        UsuarioDTO usuario = null;
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IUsuarioDAO dao = factory.getUsuarioDAO();
            usuario = dao.consultaUsuarioPorId(login);
        } catch (Exception daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTAR_USUARIO
                    + Constantes.SL + daoE.getMessage());
        }
    return usuario;
    }
    
    /**
     * Devuelve los roles que corresponde con un usuario.
     * @param   login    el login para buscar los roles
     * @return  Listado de roles que pertenecen al login pasado por parametro
     * @throws  RemoteException en caso de producirse un fallo de comunicaciones
     * @throws  GestorConexionException En caso de producirse un error en el acceso
     *          a datos
     */
    @Override
    public List<RolDTO> consultarRoles (String login) throws RemoteException, GestorConexionException {
        
        UsuarioDTO usuario = null;
        List<RolDTO> roles = new ArrayList<RolDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IUsuarioDAO dao = factory.getUsuarioDAO();
            roles = dao.getRoles(login);
        } catch (Exception daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTAR_ROLES
                    + Constantes.SL + daoE.getMessage());
        }
		return roles;
    }
    
    /**
     * Permite grabar una solicitud nueva
     * @param   solicitud       La solicitud a insertar
     * @param   fisicas         Características físicas solicitadas
     * @param   equipamiento    Equipamiento solicitado
     * @param   cantidad        Cantidad del equipamiento solicitado
     * @return  boolean         true: Si la solicitud se ha insertado correctamente,
     *                          false: en caso contrario
     * @throws  RemoteException en caso de producirse un fallo de comunicaciones
     * @throws  GestorConexionException En caso de producirse un error en el acceso
     *          a datos
     */
    @Override
    public boolean grabarSolicitud(SolicitudDTO solicitud, List<CFisicaDTO> fisicas, 
            List<EquipamientoDTO> equipamiento, List<Integer> cantidad) throws RemoteException, GestorConexionException {
        boolean ok = false;
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            dao.grabarSolicitud(solicitud,fisicas,equipamiento,cantidad);
            ok = true;

//             Liberamos recursos
            factory = null;
            dao = null;
        } catch (DAOFactoryException daoF) {
            throw new GestorConexionException(GestorConexionException.ERROR_LISTA_SOLICITUDES
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_GRABAR_SOLICITUD
                    + Constantes.SL + daoE.getMessage());
        }
        return ok;
    }
    
      /**
     * Obtiene la solicitud de la que se envía por parámetro su identificador
     * @param idSolicitud      El identificador de solicitud
     * @return La solicitud de la que se quieren obtener todos sus datos
     * @throws RemoteException
     * @throws GestorConexionException
     */

    @Override
    public SolicitudDTO getSolicitud(int idSolicitud) throws RemoteException, GestorConexionException {
        SolicitudDTO solicitud = new SolicitudDTO();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            solicitud = dao.getSolicitud(idSolicitud);
//             Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTA_SOLICITUD
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTA_SOLICITUD
                    + Constantes.SL + daoE.getMessage());
        }
        return solicitud;
    }
    
    /**
     * Obtiene un listado de la base de datos con todas las solicitudes que cumplen
     * con los filtros establecidos.
     * @param pais      El país por el que se quiere filtrar
     * @param provincia La provincia por la que se quiere filtrar
     * @param ciudad    La ciudad por la que se quiere filtrar
     * @param tiposSol  Un array con la lista de tipos de solicitudes elegidas
     * @param estados   Un array con la lista de los estados de la solicitud
     * @param login     Id del cliente solicitante
     * @return La lista de las solicitudes filtradas por localización, tipos,
     * estados, y cliente solicitante
     * @throws RemoteException
     * @throws GestorConexionException
     */
    @Override
    public List<SolicitudDTO> listaSolicitudes(LocalizacionDTO local, List<Integer> tiposSol,
        Integer estado, String login) throws RemoteException, GestorConexionException {

        List<SolicitudDTO> solicitudes = new ArrayList<SolicitudDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            solicitudes = dao.listaSolicitudes(local,tiposSol,estado,login);
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorConexionException(GestorConexionException.ERROR_LISTA_SOLICITUDES
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_LISTA_SOLICITUDES
                    + Constantes.SL + daoE.getMessage());
        }
        return solicitudes;
    }
    
    /**
     * Obtiene un listado de la base de datos con todas las solicitudes que cumplen
     * con los filtros establecidos.
     * @param pais      El país por el que se quiere filtrar
     * @param provincia La provincia por la que se quiere filtrar
     * @param ciudad    La ciudad por la que se quiere filtrar
     * @param tiposRes  Un array con la lista de tipos de solicitudes elegidas
     * @param estado    Integer con el estado de la reserva
     * @param login     Id del cliente solicitante
     * @return La lista de las solicitudes filtradas por localización, tipos,
     * estados, y cliente solicitante
     * @throws RemoteException
     * @throws GestorConexionException
     */
    @Override
    public List<SolicitudDTO> listaReservas(LocalizacionDTO local, List<Integer> tiposRes,
            Integer estado,String login) throws RemoteException, GestorConexionException {

        List<SolicitudDTO> solicitudes = new ArrayList<SolicitudDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            solicitudes = dao.listaReservas(local,tiposRes,estado,login);
            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorConexionException(GestorConexionException.ERROR_LISTA_RESERVAS
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_LISTA_RESERVAS
                    + Constantes.SL + daoE.getMessage());
        }
        return solicitudes;
    }
    /**
     * Pone en estado Solicitud_Cancelada la solicitud la que se envía por parámetro su identificador
     * @param idSolicitud      El identificador de solicitud
     * @throws RemoteException
     * @throws GestorConexionException
     */
    @Override
    public boolean cancelarSolicitud(int idSolicitud) throws RemoteException, GestorConexionException {
        boolean realizado = false;
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            realizado = dao.cancelarSolicitud(idSolicitud);
//          Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTA_SOLICITUD
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTA_SOLICITUD
                    + Constantes.SL + daoE.getMessage());
        }
        return realizado;
    }
    
    /**
     * Pone en estado Reserva_Cancelada la reserva la que se envía por parámetro su identificador
     * @param idReserva     El identificador de reserva
     * @throws RemoteException
     * @throws GestorConexionException
     */
    @Override
    public boolean cancelarReserva(int idReserva) throws RemoteException, GestorConexionException {
        boolean realizado = false;
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            realizado = dao.cancelarReserva(idReserva);
//             Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTA_RESERVA
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorConexionException(GestorConexionException.ERROR_CONSULTA_RESERVA
                    + Constantes.SL + daoE.getMessage());
        }
        return realizado;
    }
}
